﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 商品接口实现
    /// </summary>
    public class ShopGoodsService : BaseService, IShopGoodsService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        public ShopGoodsService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<ShopGoods?> QueryAsync(Expression<Func<ShopGoods, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<ShopGoods>()
                .Include(x => x.GoodsProducts).ThenInclude(x => x.GroupPrices)
                .Include(x => x.GoodsAlbums)
                .Include(x => x.FieldValues)
                .Include(x => x.LabelRelations).ThenInclude(x => x.ShopLabel)
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ShopCategory)
                .Include(x => x.GoodsSkus)
                .Include(x => x.Brand)
                .Include(x => x.Merchant)
                .FirstOrDefaultAsync(funcWhere);
            if (result != null)
            {
                result.GoodsAlbums = result.GoodsAlbums.OrderBy(a => a.SortId).ToList();
            }
            /*if (result != null)
            {
                result.GoodsSkus = result.GoodsSkus.OrderBy(s => s.SkuId).ToList();
            }*/
            return result;
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<ShopGoods>> QueryListAsync(int top, Expression<Func<ShopGoods, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<ShopGoods>()
                .Include(x => x.GoodsProducts)//.ThenInclude(x => x.GroupPrices)
                .Include(x => x.GoodsAlbums)
                //.Include(x => x.FieldValues)
                .Include(x => x.LabelRelations).ThenInclude(x => x.ShopLabel)
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ShopCategory)
                //.Include(x => x.GoodsSkus)
                .Include(x => x.Brand)
                .Include(x => x.Merchant)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<ShopGoods>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<ShopGoods, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<ShopGoods>()
                .Include(x => x.GoodsProducts)//.ThenInclude(x => x.GroupPrices)
                .Include(x => x.GoodsAlbums)
                //.Include(x => x.FieldValues)
                .Include(x => x.LabelRelations).ThenInclude(x => x.ShopLabel)
                .Include(x => x.CategoryRelations).ThenInclude(x => x.ShopCategory)
                //.Include(x => x.GoodsSkus)
                .Include(x => x.Brand)
                .Include(x => x.Merchant)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<ShopGoods>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 查询货品分页列表
        /// </summary>
        public async Task<PaginationList<ShopGoodsProduct>> QueryProductPageAsync(int pageSize, int pageIndex, Expression<Func<ShopGoodsProduct, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<ShopGoodsProduct>()
                .Include(x => x.ShopGoods).ThenInclude(c => c!.CategoryRelations).ThenInclude(t => t.ShopCategory)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<ShopGoodsProduct>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 获取记录总数量
        /// </summary>
        public async Task<int> QueryCountAsync(Expression<Func<ShopGoods, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            return await _context.Set<ShopGoods>().Where(funcWhere).CountAsync();
        }

        /// <summary>
        /// 添加一条记录
        /// </summary>
        public async Task<ShopGoodsDto> AddAsync(ShopGoodsEditDto modelDto, bool isLock, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查商户是否正确
            if(await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == modelDto.MerchantId) == null)
            {
                throw new ResponseException("商户不存在或已删除");
            }
            //检查品牌是否正确
            if (await _context.Set<ShopBrand>().FirstOrDefaultAsync(x => x.Id == modelDto.BrandId) == null)
            {
                throw new ResponseException("品牌不存在或已删除");
            }
            //检查扩展属性模型是否正确
            if (modelDto.FieldId > 0 && await _context.Set<ShopField>().FirstOrDefaultAsync(x => x.Id == modelDto.FieldId) == null)
            {
                throw new ResponseException("扩展属性不存在或已删除");
            }
            //检查类别是否正确
            if (modelDto.CategoryRelations != null)
            {
                var categoryIds = modelDto.CategoryRelations.Select(x => x.CategoryId);
                var categoryList = await _context.Set<ShopCategory>().Where(x => categoryIds.Contains(x.Id)).ToListAsync();
                if (categoryList != null && categoryIds.Except(categoryList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("类别列表有误，请检查后操作");
                }
            }
            //检查标签是否正确
            if (modelDto.LabelRelations != null)
            {
                var labelIds = modelDto.LabelRelations.Select(x => x.LabelId);
                var labelList = await _context.Set<ShopLabel>().Where(x => labelIds.Contains(x.Id)).ToListAsync();
                if (labelList != null && labelIds.Except(labelList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("标签列表有误，请检查后操作");
                }
            }
            //检查商品规格是否正确
            if (modelDto.GoodsSkus != null)
            {
                var SkuIds = modelDto.GoodsSkus.Select(x => x.SkuId);
                var skuList = await _context.Set<ShopSkus>().Where(x => SkuIds.Contains(x.Id)).ToListAsync();
                if (skuList != null && SkuIds.Except(skuList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("商品规格列表有误，请检查后操作");
                }
            }

            //映射成实体
            var model = _mapper.Map<ShopGoods>(modelDto);
            //内容摘要提取内容前250个字符
            if (string.IsNullOrWhiteSpace(modelDto.Zhaiyao) && !string.IsNullOrWhiteSpace(modelDto.Content))
            {
                model.Zhaiyao = HtmlHelper.CutString(modelDto.Content, 250);
            }
            //记录当前用户名
            model.AddBy = await _userService.GetUserNameAsync();
            model.AddTime = DateTime.Now;
            //是否需要审核
            if (isLock)
            {
                model.IsLock = 1;
            }
            //上架或下架时间
            if (model.Status == 0)
            {
                model.UpTime = DateTime.Now;
            }

            //开启事务
            using (var transaction = await _context.Database.BeginTransactionAsync())
            {
                try
                {
                    //保存商品信息
                    await _context.Set<ShopGoods>().AddAsync(model);
                    await this.SaveAsync();
                    //保存分类规格筛选,用于查询
                    if (model.CategoryRelations != null && model.GoodsSkus != null)
                    {
                        foreach(var cmodelt in model.CategoryRelations)
                        {
                            foreach(var smodelt in model.GoodsSkus.Where(x => x.ParentId == 0))
                            {
                                ShopCategorySku modelt = new()
                                {
                                    CategoryId = cmodelt.CategoryId,
                                    SkuId = smodelt.Id,
                                    GoodsId = model.Id
                                };
                                await _context.Set<ShopCategorySku>().AddAsync(modelt);
                                await this.SaveAsync();
                            }
                        }
                    }
                    //提交事务
                    await transaction.CommitAsync();
                }
                catch
                {
                    //回滚事务
                    await transaction.RollbackAsync();
                    throw new ResponseException("保存时发生意外错误");
                }
            }
            //映射成DTO
            var result = _mapper.Map<ShopGoodsDto>(model);
            return result;
        }

        /// <summary>
        /// 修改一条记录
        /// </summary>
        public async Task<bool> UpdateAsync(long id, ShopGoodsEditDto modelDto, bool isLock, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //检查商户是否正确
            if (await _context.Set<Merchants>().FirstOrDefaultAsync(x => x.Id == modelDto.MerchantId) == null)
            {
                throw new ResponseException("商户不存在或已删除");
            }
            //检查品牌是否正确
            if (await _context.Set<ShopBrand>().FirstOrDefaultAsync(x => x.Id == modelDto.BrandId) == null)
            {
                throw new ResponseException("品牌不存在或已删除");
            }
            //检查扩展属性模型是否正确
            if (modelDto.FieldId > 0 && await _context.Set<ShopField>().FirstOrDefaultAsync(x => x.Id == modelDto.FieldId) == null)
            {
                throw new ResponseException("扩展属性不存在或已删除");
            }
            //检查类别是否正确
            if (modelDto.CategoryRelations != null)
            {
                var categoryIds = modelDto.CategoryRelations.Select(x => x.CategoryId);
                var categoryList = await _context.Set<ShopCategory>().Where(x => categoryIds.Contains(x.Id)).ToListAsync();
                if (categoryList != null && categoryIds.Except(categoryList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("类别列表有误，请检查后操作");
                }
            }
            //检查标签是否正确
            if (modelDto.LabelRelations != null)
            {
                var labelIds = modelDto.LabelRelations.Select(x => x.LabelId);
                var labelList = await _context.Set<ShopLabel>().Where(x => labelIds.Contains(x.Id)).ToListAsync();
                if (labelList != null && labelIds.Except(labelList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("标签列表有误，请检查后操作");
                }
            }
            //检查商品规格是否正确
            if (modelDto.GoodsSkus != null)
            {
                var SkuIds = modelDto.GoodsSkus.Select(x => x.SkuId);
                var skuList = await _context.Set<ShopSkus>().Where(x => SkuIds.Contains(x.Id)).ToListAsync();
                if (skuList != null && SkuIds.Except(skuList.Select(x => x.Id)).Count() > 0)
                {
                    throw new ResponseException("商品规格列表有误，请检查后操作");
                }
            }

            //根据ID获取记录
            var model = await _context.Set<ShopGoods>().Where(x => x.Id == id)
                .Include(x => x.GoodsProducts).ThenInclude(x => x.GroupPrices)
                .Include(x => x.GoodsAlbums)
                .Include(x => x.FieldValues)
                .Include(x => x.LabelRelations)
                .Include(x => x.CategoryRelations)
                .Include(x => x.GoodsSkus)
                .Include(x => x.Brand)
                .FirstOrDefaultAsync();
            //如果不存在则抛出异常
            if (model == null)
            {
                throw new ResponseException("商品不存在或已删除");
            }

            //内容摘要提取内容前250个字符
            if (string.IsNullOrWhiteSpace(modelDto.Zhaiyao) && !string.IsNullOrWhiteSpace(modelDto.Content))
            {
                model.Zhaiyao = HtmlHelper.CutString(modelDto.Content, 250);
            }
            //上架或下架时间
            if (model.Status != modelDto.Status && modelDto.Status == 0)
            {
                model.UpTime = DateTime.Now;
            }
            //是否需要审核
            if (isLock)
            {
                model.IsLock = 1;
            }
            //设置更新人和更新时间
            model.UpdateBy = await _userService.GetUserNameAsync();
            model.UpdateTime = DateTime.Now;
            _mapper.Map(modelDto, model); //AutoMapper将DTO映射到源数据
            //开启事务
            using (var transaction = await _context.Database.BeginTransactionAsync())
            {
                try
                {
                    //先查找分类规格筛选并删除
                    var skuList = await _context.Set<ShopCategorySku>().Where(x => x.GoodsId == model.Id).ToListAsync();
                    if (skuList != null)
                    {
                        _context.Set<ShopCategorySku>().RemoveRange(skuList);
                        await this.SaveAsync();
                    }
                    //保存商品信息
                    _context.Set<ShopGoods>().Update(model);
                    await this.SaveAsync();
                    //重新添加分类规格筛选,用于查询
                    if (model.CategoryRelations != null && model.GoodsSkus != null)
                    {
                        foreach (var cmodelt in model.CategoryRelations)
                        {
                            foreach (var smodelt in model.GoodsSkus.Where(x => x.ParentId == 0))
                            {
                                ShopCategorySku modelt = new()
                                {
                                    CategoryId = cmodelt.CategoryId,
                                    SkuId = smodelt.Id,
                                    GoodsId = model.Id
                                };
                                await _context.Set<ShopCategorySku>().AddAsync(modelt);
                                await this.SaveAsync();
                            }
                        }
                    }
                    //提交事务
                    await transaction.CommitAsync();
                }
                catch
                {
                    //回滚事务
                    await transaction.RollbackAsync();
                    throw new ResponseException("保存时发生意外错误");
                }
            }
            return true;
        }

        /// <summary>
        /// 根据条件删除一条记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<ShopGoods, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //删除商品主从表
            var list = await _context.Set<ShopGoods>()
                .Include(x => x.GoodsProducts).ThenInclude(x=>x.GroupPrices)
                .Include(x => x.GoodsAlbums)
                .Include(x => x.FieldValues)
                .Include(x => x.LabelRelations)
                .Include(x => x.CategoryRelations)
                .Include(x => x.GoodsSkus)
                .Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            //遍历结果并删除
            foreach (var modelt in list)
            {
                //删除优惠券与商品关联表
                var couponList = await _context.Set<ShopCouponGoodsRelation>().Where(x => x.GoodsId == modelt.Id).ToListAsync();
                if (couponList != null)
                {
                    _context.Set<ShopCouponGoodsRelation>().RemoveRange(couponList);
                }
                //查找分类规格筛选表并删除
                var skuList = await _context.Set<ShopCategorySku>().Where(x => x.GoodsId == modelt.Id).ToListAsync();
                if (skuList != null)
                {
                    _context.Set<ShopCategorySku>().RemoveRange(skuList);
                }
                //将商品加入追踪
                _context.Set<ShopGoods>().Attach(modelt);
            }
            _context.Set<ShopGoods>().RemoveRange(list);
            //提交执行删除
            return await this.SaveAsync();
        }

        /// <summary>
        /// 更新浏览量(局部更新)
        /// </summary>
        public async Task<int> UpdateClickAsync(ShopGoods model, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var entry = _context.Entry<ShopGoods>(model);
            //设置修改状态
            entry.State = EntityState.Unchanged;
            entry.Property(x => x.Click).IsModified = true;
            //提交保存
            bool result = await this.SaveAsync();
            if (result)
            {
                return model.Click;
            }
            return 0;
        }
    }
}
